;;; ebcdic-ascii-utils.el --- EBCIDIC <> ASCII conversion utils

;; Version: 0.1.0
;; Author: AlexDL
;; Url: https://notabug.org/alexdl/ebcdic-ascii-utils
;; Keywords: ebcdic

;;; Commentary:
;;; Code:
(setq ebcdic-to-ascii-table
      #s(hash-table
         size 30
         test equal
         data ("00" "00" "01" "01" "02" "02" "03" "03"
               "04" "1A" "05" "09" "06" "1A" "07" "7F"
               "08" "1A" "09" "1A" "0A" "1A" "0B" "0B"
               "0C" "0C" "0D" "0D" "0E" "0E" "0F" "0F"
               "10" "10" "11" "11" "12" "12" "13" "13"
               "14" "1A" "15" "1A" "16" "08" "17" "1A"
               "18" "18" "19" "19" "1A" "1A" "1B" "1A"
               "1C" "1C" "1D" "1D" "1E" "1E" "1F" "1F"
               "20" "1A" "21" "1A" "22" "1A" "23" "1A"
               "24" "1A" "25" "0A" "26" "17" "27" "1B"
               "28" "1A" "29" "1A" "2A" "1A" "2B" "1A"
               "2C" "1A" "2D" "05" "2E" "06" "2F" "07"
               "30" "1A" "31" "1A" "32" "16" "33" "1A"
               "34" "1A" "35" "1A" "36" "1A" "37" "04"
               "38" "1A" "39" "1A" "3A" "1A" "3B" "1A"
               "3C" "14" "3D" "15" "3E" "1A" "3F" "1A"
               "40" "20" "41" "1A" "42" "1A" "43" "1A"
               "44" "1A" "45" "1A" "46" "1A" "47" "1A"
               "48" "1A" "49" "1A" "4A" "5B" "4B" "2E"
               "4C" "3C" "4D" "28" "4E" "2B" "4F" "21"
               "50" "26" "51" "1A" "52" "1A" "53" "1A"
               "54" "1A" "55" "1A" "56" "1A" "57" "1A"
               "58" "1A" "59" "1A" "5A" "5D" "5B" "24"
               "5C" "2A" "5D" "29" "5E" "3B" "5F" "5E"
               "60" "2D" "61" "1A" "62" "1A" "63" "1A"
               "64" "1A" "65" "1A" "66" "1A" "67" "1A"
               "68" "1A" "69" "1A" "6A" "7C" "6B" "2C"
               "6C" "25" "6D" "5F" "6E" "3E" "6F" "3F"
               "70" "1A" "71" "1A" "72" "1A" "73" "1A"
               "74" "1A" "75" "1A" "76" "1A" "77" "1A"
               "78" "1A" "79" "60" "7A" "3A" "7B" "23"
               "7C" "40" "7D" "27" "7E" "3D" "7F" "22"
               "80" "1A" "81" "61" "82" "62" "83" "63"
               "84" "64" "85" "65" "86" "66" "87" "67"
               "88" "68" "89" "69" "8A" "1A" "8B" "1A"
               "8C" "1A" "8D" "1A" "8E" "1A" "8F" "1A"
               "90" "1A" "91" "6A" "92" "6B" "93" "6C"
               "94" "6D" "95" "6E" "96" "6F" "97" "70"
               "98" "71" "99" "72" "9A" "1A" "9B" "1A"
               "9C" "1A" "9D" "1A" "9E" "1A" "9F" "1A"
               "A0" "1A" "A1" "7E" "A2" "73" "A3" "74"
               "A4" "75" "A5" "76" "A6" "77" "A7" "78"
               "A8" "79" "A9" "7A" "AA" "1A" "AB" "1A"
               "AC" "1A" "AD" "1A" "AE" "1A" "AF" "1A"
               "B0" "1A" "B1" "1A" "B2" "1A" "B3" "1A"
               "B4" "1A" "B5" "1A" "B6" "1A" "B7" "1A"
               "B8" "1A" "B9" "1A" "BA" "1A" "BB" "1A"
               "BC" "1A" "BD" "1A" "BE" "1A" "BF" "1A"
               "C0" "7B" "C1" "41" "C2" "42" "C3" "43"
               "C4" "44" "C5" "45" "C6" "46" "C7" "47"
               "C8" "48" "C9" "49" "CA" "1A" "CB" "1A"
               "CC" "1A" "CD" "1A" "CE" "1A" "CF" "1A"
               "D0" "7D" "D1" "4A" "D2" "4B" "D3" "4C"
               "D4" "4D" "D5" "4E" "D6" "4F" "D7" "50"
               "D8" "51" "D9" "52" "DA" "1A" "DB" "1A"
               "DC" "1A" "DD" "1A" "DE" "1A" "DF" "1A"
               "E0" "5C" "E1" "1A" "E2" "53" "E3" "54"
               "E4" "55" "E5" "56" "E6" "57" "E7" "58"
               "E8" "59" "E9" "5A" "EA" "1A" "EB" "1A"
               "EC" "1A" "ED" "1A" "EE" "1A" "EF" "1A"
               "F0" "30" "F1" "31" "F2" "32" "F3" "33"
               "F4" "34" "F5" "35" "F6" "36" "F7" "37"
               "F8" "38" "F9" "39" "FA" "1A" "FB" "1A"
               "FC" "1A" "FD" "1A" "FE" "1A" "FF" "1A")))

(defun ebcdic-hex-to-ascii (data)
  "Convert DATA from EBCIDIC to ASCII."
  (let ((msg (upcase data))
        (i 0)
        (symb nil)
        (ch nil)
        (result nil))
    (while (<= i (- (length msg) 2))
      (setf symb (substring msg i (+ i 2)))
      (setf i (+ i 2))
      (setf ch (gethash symb ebcdic-to-ascii-table))
      (push (format "%c" (string-to-number ch 16)) result))
      ;;(message "EBCDIC %s is ASCII %s %c " symb ch (string-to-number ch 16))
    ;;(message "%s" (reverse (mapconcat 'identity result "")))
    (format "%s" (reverse (mapconcat 'identity result "")))))

(defun ebcdic-hex-to-string ()
  "Convert selected EBCDIC hex to ASCII string."
  (interactive)
  (let ((result (ebcdic-hex-to-ascii (buffer-substring-no-properties (region-beginning) (region-end))))
        (case-replace nil))
    (replace-regexp ".*" result nil (region-beginning) (region-end) )))

(provide 'ebcdic-ascii-utils)

;;; ebcdic-ascii-utils.el ends here
